package com.gitee.qdbp.general.system.biz.permission.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.able.jdbc.ordering.OrderPaging;
import com.gitee.qdbp.able.jdbc.paging.PageList;
import com.gitee.qdbp.able.result.ResultCode;
import com.gitee.qdbp.base.system.model.IAccountType;
import com.gitee.qdbp.general.system.api.permission.basic.IResourceCoreBasic;
import com.gitee.qdbp.general.system.api.permission.basic.IRoleCoreBasic;
import com.gitee.qdbp.general.system.api.permission.basic.IRoleResourceRefBasic;
import com.gitee.qdbp.general.system.api.permission.model.ResourceCoreBean;
import com.gitee.qdbp.general.system.api.permission.model.ResourceCoreWhere;
import com.gitee.qdbp.general.system.api.permission.model.RoleCoreBean;
import com.gitee.qdbp.general.system.api.permission.model.RoleCoreWhere;
import com.gitee.qdbp.general.system.api.permission.model.RoleResourceRefBean;
import com.gitee.qdbp.general.system.api.permission.model.RoleResourceRefWhere;
import com.gitee.qdbp.general.system.api.permission.service.IResourceCoreQueryer;
import com.gitee.qdbp.general.system.enums.SysResState;
import com.gitee.qdbp.general.system.enums.SysResType;
import com.gitee.qdbp.tools.utils.VerifyTools;

/**
 * 资源信息业务处理类
 *
 * @author zhh
 * @version 170215
 */
@Service
@Transactional(readOnly = true)
public class ResourceCoreQueryer implements IResourceCoreQueryer {
    
    /** 日志对象 **/
    private static Logger log = LoggerFactory.getLogger(ResourceCoreQueryer.class);

    @Autowired
    private IRoleCoreBasic roleCoreBasic;
    @Autowired
    private IResourceCoreBasic resourceCoreBasic;
    @Autowired
    private IRoleResourceRefBasic roleResourceRefBasic;

    @Override
    public ResourceCoreBean find(String id) throws ServiceException {
        return resourceCoreBasic.findById(id);
    }

    @Override
    public ResourceCoreBean find(ResourceCoreWhere where) throws ServiceException {
        if (VerifyTools.isBlank(where.getSceneType())) {
            log.error("params is required: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        return resourceCoreBasic.find(where);
    }

    @Override
    public PageList<ResourceCoreBean> list(ResourceCoreWhere where, OrderPaging paging) throws ServiceException {
        if (VerifyTools.isBlank(where.getSceneType())) {
            log.error("params is required: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        return resourceCoreBasic.list(where, paging);
    }

    @Override
    public List<ResourceCoreBean> listByUserId(String userId, ResourceCoreWhere where, OrderPaging paging,
            boolean parents) throws ServiceException {

        if (VerifyTools.isBlank(where.getSceneType())) {
            log.error("params is required: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 查询登录用户所拥有的权限
        PageList<ResourceCoreBean> resources = resourceCoreBasic.listByUserId(userId, where, paging);
        if (VerifyTools.isBlank(resources)) {
            return new ArrayList<>();
        }

        if (!parents) {
            return resources.toList();
        } else {
            // 追加所有上级
            return appendParents(where.getSceneType(), resources.toList());
        }
    }

    @Override
    public List<ResourceCoreBean> listByUserType(IAccountType userType, String scene, boolean parents)
            throws ServiceException {
        if (VerifyTools.isBlank(scene)) {
            log.error("params is required: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        PageList<RoleCoreBean> roles;
        { // 查询默认角色
            RoleCoreWhere where = new RoleCoreWhere();
            where.setUserType(userType);
            where.setDefaults(true);
            roles = roleCoreBasic.list(where, OrderPaging.NONE);
            if (VerifyTools.isBlank(roles)) return new ArrayList<>();
        }

        PageList<RoleResourceRefBean> refs;
        { // 查询角色资源关联
            Set<String> roleIds = new HashSet<>();
            for (RoleCoreBean role : roles) {
                roleIds.add(role.getId());
            }
            RoleResourceRefWhere where = new RoleResourceRefWhere();
            where.setSceneType(scene);
            where.setRoleIds(new ArrayList<>(roleIds));
            refs = roleResourceRefBasic.list(where, OrderPaging.NONE);
            if (VerifyTools.isBlank(refs)) return new ArrayList<>();
        }

        PageList<ResourceCoreBean> resources;
        { // 查询资源列表
            Set<String> resIds = new HashSet<>();
            for (RoleResourceRefBean ref : refs) {
                resIds.add(ref.getResourceId());
            }
            ResourceCoreWhere where = new ResourceCoreWhere();
            where.setSceneType(scene);
            where.setState(SysResState.NORMAL);
            where.setIds(new ArrayList<>(resIds));
            resources = resourceCoreBasic.list(where, OrderPaging.NONE);
            if (VerifyTools.isBlank(resources)) return new ArrayList<>();
        }

        if (!parents) {
            return resources.toList();
        } else {
            // 追加所有上级
            return appendParents(scene, resources.toList());
        }
    }

    // 追加所有上级
    // role_resource_ref表记录的只有OPERATE这一级, 没有记模块/菜单组/菜单
    private List<ResourceCoreBean> appendParents(String scene, List<ResourceCoreBean> operates)
            throws ServiceException {

        // 查询所有模块/菜单组/菜单
        ResourceCoreWhere where = new ResourceCoreWhere();
        where.setSceneType(scene);
        where.setState(SysResState.NORMAL);
        where.addType(SysResType.MODULE, SysResType.GROUP, SysResType.MENU);
        PageList<ResourceCoreBean> supers = resourceCoreBasic.list(where, OrderPaging.NONE);

        Map<String, ResourceCoreBean> map = new HashMap<>();
        for (ResourceCoreBean bean : supers) {
            map.put(bean.getId(), bean);
        }

        Set<ResourceCoreBean> all = new HashSet<>();
        // 组合(找出入参指定的资源的所有上级)
        if (operates != null) {
            for (ResourceCoreBean bean : operates) {
                ResourceCoreBean curr = bean;
                while (curr != null) {
                    all.add(curr);
                    curr = map.get(curr.getParentId());
                }
            }
        }

        List<ResourceCoreBean> list = new ArrayList<>(all);
        // 排序
        Collections.sort(list);
        return list;
    }
}
